#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/module.h>
#include <linux/printk.h>

static int __init pidtest_initfunc(void)
{
    printk(KERN_INFO "call pidtest_initfunc(...) func.\n");

    // 1. find_get_pid()
    struct pid *kernelpid = find_get_pid(current->pid);

    if (kernelpid) {
        // 打印 atomic_t 类型的 count 需要使用 atomic_read()
        printk(KERN_INFO "print processor describe count value: %d\n", kernelpid->count);
        printk(KERN_INFO "print processor describe level value: %d\n", kernelpid->level);
        printk(KERN_INFO "print processor describe numbers value: %d\n", kernelpid->numbers[kernelpid->level].nr);

        // 减少 pid 引用计数，防止内存泄漏
        put_pid(kernelpid);
    } else {
        printk(KERN_ERR "Failed to find pid.\n");
    }

    // 2. pid_nr()
    int iNr = pid_nr(kernelpid);
    if (iNr) {
        printk(KERN_INFO "print processor describe global code: %d\n", iNr);
        printk(KERN_INFO "print processor describe current tgid: %d\n", current->tgid);
    }else {
        printk(KERN_ERR "Failed to Call func pid_nr() .\n");
    }

    // 3. pid_task()
    struct task_struct *ttask = pid_task(kernelpid,PIDTYPE_PID);
    if (ttask) {
        printk(KERN_INFO "print task current state: %1d\n", ttask->stats);
        printk(KERN_INFO "print task current PID: %1d\n", ttask->pid);
    }else {
        printk(KERN_ERR "Failed to Call func pid_task() .\n");
    }

    // 4. __task_pid_nr_ns()
    pid_t rest = __task_pid_nr_ns(ttask, PIDTYPE_PID, kernelpid->numbers[kernelpid->level].ns);
    if (rest) {
        printk("call __task_pid_nr_ns() func, output result: %d\n", rest);
    }

    printk("exit pidtest_initfunc() func.\n");
    return 0;
}

static void __exit pidtest_exitfunc(void)
{
    printk(KERN_INFO "normal exit linux kernel...\n");
}

MODULE_LICENSE("GPL");

module_init(pidtest_initfunc);
module_exit(pidtest_exitfunc);
